package pun.potato;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.FacebookException;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.widget.WebDialog;
import com.facebook.widget.WebDialog.OnCompleteListener;

public class MainFragment extends Fragment{
	
	//MAIN MENU VARIABLES
	Button quitButton;
	Button playButton;
	Button specButton;
	Button sendRequest;
	TextView title;
	ImageView fbook;
	ProgressDialog pDialog;
	boolean isFacebookUser;
	int difficulty = 2; //by default set it to easy
	int userid;
	String username;
	int partnerId;
	String partnerName;
	String topic = "topicForHost";
	int threadId;
	String partnerFacebookId = "";
	int playerMojo;
	int partnerMojo;
	ArrayList<String> sendIds = new ArrayList<String>();
	ArrayList<String> conversation = new ArrayList<String>();
	ArrayList<String> names = new ArrayList<String>();
	ArrayList<Integer> pun_ids = new ArrayList<Integer>();
	public boolean checkFriendGame = true;
	final static int TIMEOUT_TIME = 15000; //15 seconds
	boolean timeout = false;
	

	private static final int RESULT_MESSAGE = 1;
	
	private UiLifecycleHelper uiHelper;
	
	private Session.StatusCallback callback = new Session.StatusCallback() {

		@Override
		public void call(Session session, SessionState state, Exception exception) {
			onSessionStateChange(session, state, exception);

		}
	};
	
	private void onSessionStateChange(Session session, SessionState state, Exception exception){
		
		//check if the user is authenticated and an incoming notifcation needs handling
//		if(state.isOpened() && requestId != null){
//			Toast.makeText(getActivity().getApplicationContext(), "Incoming request", Toast.LENGTH_LONG).show();
//			requestId = null;
//		}
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		
		final View view = inflater.inflate(R.layout.mainmenu, container, false);
		Bundle e = getActivity().getIntent().getExtras();
		if (e != null) {
			userid = e.getInt("userid");
			username = e.getString("username");
			isFacebookUser = e.getBoolean("facebookUser");
			partnerFacebookId = e.getString("partnerFacebookId");
			playerMojo = e.getInt("mojo");
		}
		
		if(!partnerFacebookId.equals("")){
			new SetupFriendGame().execute("start");
			//Toast.makeText(getActivity(), "A new game should be starting now.", Toast.LENGTH_LONG).show();
		}

		playButton = (Button)view.findViewById(R.id.PlayButton);
		specButton = (Button)view.findViewById(R.id.button2);
		quitButton = (Button)view.findViewById(R.id.logout);
		sendRequest = (Button)view.findViewById(R.id.play_with_friend);
		//fbook = (ImageView)view.findViewById(R.id.fbook);
		title = (TextView)view.findViewById(R.id.Pundamodium);
		Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Ranger.ttf");
		title.setTypeface(tf);
		
		
		
		playButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				checkFriendGame = false;
				RadioGroup rg = (RadioGroup)view.findViewById(R.id.difficulty);
				int selected = rg.getCheckedRadioButtonId();
					RadioButton rb = (RadioButton)view.findViewById(selected);
					if(rb == (RadioButton)view.findViewById(R.id.med)){
						difficulty = 2;
					} else if(rb == (RadioButton)view.findViewById(R.id.hard)){
						difficulty = 3;
					} else {
						difficulty = 1;
					}
				new SearchForPlayers().execute("start");
			}

		});
		
		specButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				checkFriendGame = false;
				startActivity(new Intent(getActivity(), SpectatorScreen.class));
			}
		});
		
		//if(isFacebookUser){
			//sendRequest.setVisibility(View.VISIBLE);
			//fbook.setVisibility(View.VISIBLE);
			sendRequest.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View v) {
					if(isFacebookUser){
					checkFriendGame = false;
					sendRequestDialog();
					} else {
						Toast.makeText(getActivity(), "You must be logged in with facebook for that!", Toast.LENGTH_SHORT).show();
					}
				}
				
			});
		//}
		//else{
		//	sendRequest.setVisibility(View.GONE);
		//}


		
		quitButton.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				checkFriendGame = false;
				if(isFacebookUser){
					Session.getActiveSession().closeAndClearTokenInformation();
				}
				getActivity().finish();
			}

		});  
		
		return view;
	}
	
	
	
	

	private void sendRequestDialog(){
		Bundle params = new Bundle();
		params.putString("message", "Engage in a Battle of Wits!.");
		
		WebDialog requestDialog = (new WebDialog.RequestsDialogBuilder(getActivity(),
				Session.getActiveSession(), params))
				.setOnCompleteListener(new OnCompleteListener(){

					@Override
					public void onComplete(Bundle values,
							FacebookException error) {
						if(error != null){
							//Toast.makeText(getActivity(), "Request was cancelled.", Toast.LENGTH_LONG).show();
						}
						else{
							final String requestId = values.getString("request");
							if(requestId != null){
								Toast.makeText(getActivity(), "Game invite sent!", Toast.LENGTH_LONG).show();
								Toast.makeText(getActivity(), "Please wait while your friend accepts the invitation.", Toast.LENGTH_LONG).show();
								checkFriendGame = true;
								new CheckFriendGame().execute("start");
							}
							else{
								//Toast.makeText(getActivity(), "Request cancelled", Toast.LENGTH_LONG).show();
							}
						}
						
					}
					
				})
				.build(); 
		requestDialog.show();
	}
	

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(requestCode == RESULT_MESSAGE){
			if(resultCode == Activity.RESULT_OK){
				sendIds = new ArrayList<String>();
				conversation = new ArrayList<String>();
				names = new ArrayList<String>();
				pun_ids = new ArrayList<Integer>();
				int returnValue = data.getExtras().getInt("returnValue");
				int points = data.getExtras().getInt("pointsAwarded");
				if(returnValue == 0){
					points = Math.abs(points);
					playerMojo -= points;
					Toast.makeText(getActivity(), "You have lost " + points + " mojo for quitting out of the game.", Toast.LENGTH_LONG).show();
				}
				else if(returnValue == 3){
					Toast.makeText(getActivity(), "You have lost the game!", Toast.LENGTH_LONG).show();
				}
				else if(returnValue == 4){
					Toast.makeText(getActivity(), "You have won " + points + " mojo for winning the game!", Toast.LENGTH_LONG).show();
					playerMojo += points;
					
					//update the user's mojo
				}
				else{
					Dialog afterPlayDialog = createAfterPlayDialog(returnValue);
					afterPlayDialog.show();
				}
			} 
		}
		uiHelper.onActivityResult(requestCode, resultCode, data);
	}
	
	
	
	

	
	
	
	private Dialog createPuntDialog(){
		final View puntDialog = View.inflate(getActivity(), R.layout.puntexplaination, null);
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle("Punting");
		TextView explaination = (TextView)puntDialog.findViewById(R.id.textView1);
		Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Ranger.ttf");
		explaination.setTypeface(tf);
		explaination.setText("In Pundamonium, your partner can 'punt' you which means you'll be punted out of the game. Make sure your puns are amusing and you won't be punted!");
		
		builder.setNegativeButton("Ok", new Dialog.OnClickListener() {

			@Override
			public void onClick(android.content.DialogInterface arg0, int arg1) {
				//cancel
			}
		});
		
		builder.setView(puntDialog);
		return builder.create();
	}
	
	private Dialog createAfterPlayDialog(int returnValue){
		//this dialog is also executed if the timer runs out
		final View afterPlayDialog = View.inflate(getActivity(), R.layout.afterplaydialog, null);
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setTitle("Oh no!");
		builder.setIcon(0);
		TextView message = (TextView)afterPlayDialog.findViewById(R.id.textView1);
		TextView whatsThis = (TextView)afterPlayDialog.findViewById(R.id.textView2);
		Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Ranger.ttf");
		message.setTypeface(tf);
		whatsThis.setTypeface(tf);
		if(returnValue == 1){
			message.setText("We're sorry, your partner has quit the game.");
			whatsThis.setText("");
			whatsThis.setClickable(false);
		}
		else if(returnValue == 2){
			message.setText("You have been punted!");
			whatsThis.setText("What is this?");
			whatsThis.setClickable(true);
			//set different color here too
			whatsThis.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View arg0) {
					Dialog puntDialog = createPuntDialog();
					puntDialog.show();
				}
				
			});
		}
		else if(returnValue == 5){
			//for the timeout timer
			message.setText("We're sorry we could not find a player for you to join. Would you like to search again?");
			whatsThis.setText("");
			whatsThis.setClickable(false);
		}
		
		if(returnValue != 5){
			builder.setNegativeButton("Ok", new Dialog.OnClickListener() {

				@Override
				public void onClick(android.content.DialogInterface arg0, int arg1) {
					//cancel
				}
			});
		}
		else{
			builder.setPositiveButton("Yes", new Dialog.OnClickListener(){

				@Override
				public void onClick(DialogInterface arg0, int arg1) {
					new SearchForPlayers().execute("start");
				}
				
			});
			builder.setNegativeButton("No", new Dialog.OnClickListener(){

				@Override
				public void onClick(DialogInterface dialog, int which) {
					//cancel
				}
				
			});
		}

		
		builder.setView(afterPlayDialog);
		return builder.create();
	}
	
	private void goToPlayScreen(){
		Intent intent = new Intent(getActivity(), PlayScreen.class);
		intent.putExtra("userid", userid);
		intent.putExtra("username", username);
		intent.putExtra("partnerId", partnerId);
		intent.putExtra("partnerName", partnerName);
		intent.putExtra("topic", topic);
		intent.putExtra("thread_id", threadId);
		intent.putExtra("sendIds", sendIds);
		intent.putExtra("playerMojo", playerMojo);
		intent.putExtra("partnerMojo", partnerMojo);
		intent.putStringArrayListExtra("conversation", conversation);
		intent.putStringArrayListExtra("names", names);
		intent.putIntegerArrayListExtra("pun_ids", pun_ids);
		
		
		//check which difficulty is checked
		
			intent.putExtra("difficulty", difficulty);
			startActivityForResult(intent, RESULT_MESSAGE);
			
			
	}
	
	class SetupFriendGame extends AsyncTask<String, String, String>{

		private boolean setupGameSuccess = false;
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			pDialog = ProgressDialog.show(getActivity(), "", "Setting up game...", true);
		}

		@Override
		protected String doInBackground(String... arg0) {
			
			String nameToSend = username.replace(" ", "%20");
			HttpClient client = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(Preferences.GetURL() + "setupFriendGame.php?id=" + userid + "&facebookId=" + partnerFacebookId + "&name=" + nameToSend + Preferences.GetLiveServerPreferences());
			
			try{
				HttpResponse response = client.execute(httpPost);
				String jsonString = EntityUtils.toString(response.getEntity());
				//Log.d("setSearching", jsonString);
				JSONObject jObject = new JSONObject(jsonString);
				String pname = jObject.getString("name");
				if(!pname.equals("")){ 
					setupGameSuccess = true;
					partnerId = jObject.getInt("id");
					partnerName = pname;
					topic = jObject.getString("topic");
					threadId = jObject.getInt("thread_id");
					partnerMojo = jObject.getInt("mojo");
				}
			}catch(IOException e){
				//Log.d("SetupFriendGame", "IOException");
			}catch(JSONException e){
				//Log.d("SetupFriendGame", "JSONException");
			}
			
			return null;
		}
		
		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			pDialog.dismiss();
			if(setupGameSuccess){
				goToPlayScreen();
			}
			else{
				Toast.makeText(getActivity(), "Oops! Something went wrong when joining your friend's game.", Toast.LENGTH_LONG).show();
			}
		}
		
	}
	
	class SearchForPlayers extends AsyncTask<String, String, String>{

		int joinCommand = 0; //0 for error, 1 for hosting a game, 2 for joining a game

		@Override
		protected void onPreExecute() {
			super.onPreExecute();

			pDialog = ProgressDialog.show(getActivity(), "", "Starting search...", true);
		}

		@Override
		protected String doInBackground(String... params) {
			String name = username.replace(" ", "%20");
			HttpClient client = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(Preferences.GetURL() + "join.php?id=" + userid + "&join=1" + "&name=" + name + "&diff="+difficulty + Preferences.GetLiveServerPreferences());

			try{
					HttpResponse response = client.execute(httpPost);
					String jsonString = EntityUtils.toString(response.getEntity());
					//Log.d("setSearching", jsonString);

					if(jsonString.charAt(0) == '0'){
						joinCommand = 0;
					}
					else if(jsonString.charAt(0) == '1'){
						//you are hosting
						joinCommand = 1;
					}
					else{ 
						//you are joining
						JSONObject object = new JSONObject(jsonString);
						partnerName = object.getString("name");
						partnerId = object.getInt("id");
						topic = object.getString("topic");
						threadId = object.getInt("thread_id");
						partnerMojo = object.getInt("mojo");
						joinCommand = 2;
					}


			}catch(ClientProtocolException e){
				Log.e("setSearching", "ClientProtocolException");
			}catch(IOException e){
				Log.e("setSearching", "IOException");
			}catch(JSONException e){
				Log.e("setSearching", "JSONException");
			}


			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			pDialog.dismiss();
			if(joinCommand == 2){
				goToPlayScreen();
			}
			else if(joinCommand == 1){
				new WaitForJoiningPlayer().execute("start");
			}
			else{
				Toast.makeText(getActivity(), "Sorry, something went wrong with your search. Please try searching again.", Toast.LENGTH_LONG).show();
			}
			//if join command == 0 we dont want to do anything because it is an error

		}

	}
	
	class WaitForJoiningPlayer extends AsyncTask<String, String, String>{

		int returnedId = 0;
		JSONObject object;
		TimeoutTimer timer;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			timeout = false;
			pDialog = ProgressDialog.show(getActivity(), "", "Waiting for player...", true);
			timer = new TimeoutTimer(TIMEOUT_TIME, 1000);
			timer.start();
		}

		@Override
		protected String doInBackground(String... arg0) {

			//constantly check for player joining
			HttpClient client = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(Preferences.GetURL() + "searchForPlayers.php?id=" + userid + Preferences.GetLiveServerPreferences());
			//Log.d("Bitches", "GOT HERE");
			try{
				while(returnedId == 0){
					if(timeout){
						break;
					}
					HttpResponse reponse = client.execute(httpPost);
					String jsonString = EntityUtils.toString(reponse.getEntity());
					object = new JSONObject(jsonString);
					returnedId = object.getInt("pid");
				}

				if(!timeout){
					//if we get here, it means the player has joined the game
					partnerId = returnedId;
					partnerName = object.getString("pname");
					partnerMojo = object.getInt("mojo"); //this mojo isn't correct
					topic = object.getString("topic");
					threadId = object.getInt("thread_id");


					JSONArray messages = object.getJSONArray("messages");
					for(int i = 0; i < messages.length(); i++){
						JSONObject mess = messages.getJSONObject(i);
						int sid = mess.getInt("sid");
						int pun_id = mess.getInt("pun_id");
						String content = mess.getString("content");
						String name = mess.getString("name");
						sendIds.add(Integer.toString(sid));
						conversation.add(content);
						names.add(name);
						pun_ids.add(pun_id); 
						//Log.d("WaitForJoiningPlayer", "sid: " + sid + " Content: " + content);
					}

					//Log.d("waitForJoiningPlayer", "You are hosting a game. Partner's id: " + partnerId + " Partner's name: " + partnerName);
				}


			}catch(ClientProtocolException e){
				//Log.e("waitForJoiningPlayer", "ClientProtocolException");
			}catch(IOException e){
				//Log.e("waitForJoiningPlayer", "IOException");
			}catch(JSONException e){
				//Log.e("waitForJoiningPlayer", "JSONException");
			}

			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			if(!timeout){
				timer.cancel();
				pDialog.dismiss();
				//when the game starts from here, this means both players are in the same game. 
				goToPlayScreen();
			}
		}

	}
	
	class CheckFriendGame extends AsyncTask<String, String, String>{

		int returnedId = 0;
		JSONObject object;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected String doInBackground(String... params) {
			
			HttpClient client = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(Preferences.GetURL() + "checkFriendGame.php?id=" + userid + Preferences.GetLiveServerPreferences());
			try{
				while(returnedId == 0){
					if(!checkFriendGame){
						break;
					}
					HttpResponse reponse = client.execute(httpPost);
					String jsonString = EntityUtils.toString(reponse.getEntity());
					object = new JSONObject(jsonString);
					returnedId = object.getInt("pid");
				}

				//if we get here, it means the player has joined the game
				partnerId = returnedId;
				partnerName = object.getString("pname");
				topic = object.getString("topic");
				threadId = object.getInt("thread_id");
				partnerMojo = object.getInt("mojo");

				//Log.d("CheckFriendGame", "You are hosting a game. Partner's id: " + partnerId + " Partner's name: " + partnerName);

			}catch(ClientProtocolException e){
				//Log.e("CheckFriendGame", "ClientProtocolException");
			}catch(IOException e){
				//Log.e("CheckFriendGame", "IOException");
			}catch(JSONException e){
				//Log.e("CheckFriendGame", "JSONException");
			}
			
			return null;
		}
		
		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			if(checkFriendGame){
				goToPlayScreen();
			}
		}
		
	}
	
	class TimeoutTimer extends CountDownTimer{

		int minutes;
		int seconds;
		
		public TimeoutTimer(long millisInFuture, long countDownInterval) {
			super(millisInFuture, countDownInterval);
			int totalSeconds = (int)(millisInFuture / 1000);
			minutes = totalSeconds / 60;
			seconds = totalSeconds % 60;
		}

		@Override
		public void onFinish() {
			timeout = true;
			pDialog.dismiss();
			new ResetAfterTimeout().execute("start");
		}

		@Override
		public void onTick(long millisUntilFinished) {
			//dont do anything
		}
		
		
	}
	
	class ResetAfterTimeout extends AsyncTask<String, String, String>{

		@Override
		protected String doInBackground(String... params) {
			
			HttpClient client = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(Preferences.GetURL() + "resetAfterTimeout.php?id=" + userid + Preferences.GetLiveServerPreferences());
			
			try{
				HttpResponse response = client.execute(httpPost);
				String jsonString = EntityUtils.toString(response.getEntity());
				//Log.d("ResetAfterTimeout", jsonString);
			}catch(IOException e){
				e.printStackTrace();
			}
			
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			Dialog afterTimeoutDialog = createAfterPlayDialog(5);
			afterTimeoutDialog.show();
		}
		
		
		
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		uiHelper = new UiLifecycleHelper(getActivity(), callback);
		uiHelper.onCreate(savedInstanceState);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		uiHelper.onDestroy();
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		uiHelper.onSaveInstanceState(outState);
	}

	@Override
	public void onPause() {
		super.onPause();
		uiHelper.onPause();
	}

	@Override
	public void onResume() {
		super.onResume();
		Session session = Session.getActiveSession();
		if(session != null && (session.isOpened() || session.isClosed())){
			onSessionStateChange(session, session.getState(), null);
		}
		uiHelper.onResume();
	}
	
	public int getUserId(){
		return userid;
	}
	
	
	
	

}
